package com.cartrentalsystem.service.impl;

import com.cartrentalsystem.context.BaseContext;
import com.cartrentalsystem.domain.po.Customers;
import com.cartrentalsystem.domain.po.User;
import com.cartrentalsystem.domain.vo.Result;
import com.cartrentalsystem.domain.vo.UserVo;
import com.cartrentalsystem.mapper.UserMapper;
import com.cartrentalsystem.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cartrentalsystem.utils.AliyunUtils;
import com.cartrentalsystem.utils.BcryptUtils;
import com.cartrentalsystem.utils.JwtUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LHD
 * @since 2025-06-12
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final RedisTemplate redisTemplate;

    @Override
    @Transactional
    public UserVo login(String username, String password, String uuid,String code,HttpServletResponse response){

        User user = this.lambdaQuery()
                .eq(User::getUsername, username)
                .one();
        if (user == null){
            throw new RuntimeException("用户名或密码错误");
        }
        if (!BcryptUtils.check(password, user.getPassword())){
            throw new RuntimeException("用户名或密码错误");
        }


        String redisCode = (String) redisTemplate.opsForValue().get("Captcha" + uuid);
        if (redisCode == null){
            throw new RuntimeException("验证码已过期");
        }
        if (!redisCode.equals(code)){
            throw new RuntimeException("验证码错误");
        }

        log.info("用户登录成功：{}", user);

        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        String jwt = JwtUtil.createJWT("LHD", 7200000, claims);
        log.info("生成jwt：{}", jwt);
        response.setHeader("Token", jwt);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        userVo.setToken(jwt);
        log.info("用户信息：{}", user);
        log.info("用户信息：{}", userVo);
        redisTemplate.opsForValue().set( "userId:"+user.getId(), userVo, 600000, TimeUnit.MILLISECONDS);
        return userVo;
    }

    @Override
    @Transactional
    public boolean updateUser(User user) {
        Long userId = BaseContext.getCurrentId();
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        userVo.setImage(user.getImage());
        redisTemplate.opsForValue().set( "userId:"+user.getId(), userVo, 600000, TimeUnit.MILLISECONDS);
        return this.lambdaUpdate()
                .eq(User::getId, user.getId())
                .set(User::getUsername, user.getUsername())
                .set(User::getName, user.getName())
                .set(User::getPhone, user.getPhone())
                .set(User::getEmail, user.getEmail())
                .set(User::getDepartment, user.getDepartment())
                .set(User::getPosition, user.getPosition())
                .update();
    }

    @Override
    @Transactional
    public Result uploadImage(MultipartFile file){
        Long userId = BaseContext.getCurrentId();
        if (file == null){
            return Result.fail("文件为空");
        }
        String objectName = "userImageAvatar" + userId + ".jpg";
        try {
            File tempDir = Files.createTempDirectory("avatar-").toFile();
            File tempFile = new File(tempDir, "userImageAvatar" + userId + ".jpg");
            file.transferTo(tempFile);
            String s = AliyunUtils.updateAtavarImage(tempFile, objectName);
            tempFile.delete();

            // 修改数据库中头像地址
            this.lambdaUpdate()
                    .eq(User::getId, userId)
                    .set(User::getImage, s)
                    .update();

            // 更新redis中的用户信息
            UserVo userVo = new UserVo();
            User one = this.lambdaQuery()
                    .eq(User::getId, userId)
                    .one();
            BeanUtils.copyProperties(one, userVo);
            userVo.setImage(s);
            redisTemplate.opsForValue().set( "userId:"+userId, userVo, 600000, TimeUnit.MILLISECONDS);


            // 上传完成之后删除临时文件
            boolean deleted = tempDir.delete();
            if (!deleted) {
                // 可以记录日志提醒删除失败
            }
            return Result.success(s);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional
    public boolean updatePassword(Long userId, String username, String oldPassword, String newPassword){
        User user = this.baseMapper.selectById(userId);
        if (user == null){
            throw new RuntimeException("用户不存在");
        }
        if (!BcryptUtils.check(oldPassword, user.getPassword())){
            throw new RuntimeException("旧密码错误");
        }
        if (BcryptUtils.check(newPassword, user.getPassword())){
            throw new RuntimeException("新密码不能与旧密码相同");
        }
        newPassword = BcryptUtils.encrypt(newPassword);
        return this.lambdaUpdate()
                .eq(User::getId, userId)
                .eq(User::getUsername, username)
                .set(User::getPassword, newPassword)
                .update();
    }

}
